/* * Copyright 2011 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.jboss.netty.util.internal; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.Deflater; /** * Utility that detects various properties specific to the current runtime * environment, such as Java version and the availability of the * {@code sun.misc.Unsafe} object. * * <br> * You can disable the use of {@code sun.misc.Unsafe} if you specify * the System property <strong>org.jboss.netty.tryUnsafe</strong> with * value of <code>false</code>. Default is <code>true</code>. */ public final class DetectionUtil { private static final int JAVA_VERSION = javaVersion0(); private static final boolean HAS_UNSAFE = hasUnsafe(AtomicInteger.class.getClassLoader()); public static boolean hasUnsafe() { return HAS_UNSAFE; } public static int javaVersion() { return JAVA_VERSION; } private static boolean hasUnsafe(ClassLoader loader) { boolean useUnsafe = Boolean.valueOf(SystemPropertyUtil.get("org.jboss.netty.tryUnsafe", "true")); if (!useUnsafe) { return false; } try { Class<?> unsafeClazz = Class.forName("sun.misc.Unsafe", true, loader); return hasUnsafeField(unsafeClazz); } catch (Exception e) { // Ignore } return false; } private static boolean hasUnsafeField(final Class<?> unsafeClass) throws PrivilegedActionException { return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() { public Boolean run() throws Exception { unsafeClass.getDeclaredField("theUnsafe"); return true; } }); } private static int javaVersion0() { try { // Check if its android, if so handle it the same way as java6. // // See https://github.com/netty/netty/issues/282 Class.forName("android.app.Application"); return 6; } catch (ClassNotFoundException e) { //Ignore } try { Deflater.class.getDeclaredField("SYNC_FLUSH"); return 7; } catch (Exception e) { // Ignore } try { Double.class.getDeclaredField("MIN_NORMAL"); return 6; } catch (Exception e) { // Ignore } return 5; } private DetectionUtil() { // only static method supported } }